package com.abo.yaas.utils;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import org.apache.commons.mail.DefaultAuthenticator;
import org.apache.commons.mail.Email;
import org.apache.commons.mail.EmailException;
import org.apache.commons.mail.SimpleEmail;

import com.abo.yaas.YaasApplication;
import com.abo.yaas.domain.Auction;
import com.abo.yaas.domain.Bid;
import com.abo.yaas.domain.User;
import com.abo.yaas.webservice.ResourceProvider;
import com.vaadin.addon.jpacontainer.JPAContainer;
import com.vaadin.addon.jpacontainer.filter.Filters;

public class EmailUtils {
    private static Properties props = null;

    private static final String EMAIL_PROPERTIES = "email.properties";

    private static void fetchProperties() throws IOException {
        final InputStream str = YaasApplication.class.getResourceAsStream(EMAIL_PROPERTIES);
        props = new Properties();
        props.load(str);
    }

    public static void newBidPlacedEmail(final List<User> recepients, final Bid bid, final Auction auction) {
        final ArrayList<String> addrs = new ArrayList<String>();
        for (final User u : recepients) {
            addrs.add(u.getEmail());
        }
        final String msg = "Bid Placed: " + bid.getAmount().toString() + " " + auction.getTitle();
        Email email;
        try {
            email = prepareMessage(msg, "Bid Placed",
                    addrs.toArray(new String[addrs.size()]));
            email.send();
        } catch (final Exception e) {
            e.printStackTrace();
        }
    }

    private static Email prepareMessage(final String msg, final String subject, final String... addresses) 
    throws IOException, EmailException {
        if (props == null) {
            fetchProperties();
        }
        final Email email = new SimpleEmail();
        email.setHostName(props.getProperty("server"));
        email.setSmtpPort(Integer.parseInt(props.getProperty("port")));
        email.setAuthenticator(new DefaultAuthenticator(props.getProperty("user"), props.getProperty("pwd")));
        email.setTLS(true);
        email.setSubject(subject);
        email.setMsg(msg);
        for (final String addr : addresses) {
            email.addTo(addr);
        }
        email.setFrom(props.getProperty("address"));
        return email;
    }

    public static void sendAuctionCreatedEmail(final Auction auction)
            throws EmailException, IOException {
        final String msg = "Auction created: " + auction.getTitle();
        final Email email = prepareMessage(msg, "New Auction Registered", auction.getOwner().getEmail());
        email.send();
    }

    public static void sendAuctionresolvedEmail(final Auction auction) {
        final JPAContainer<Bid> container = new JPAContainer<Bid>(Bid.class);
        container.setEntityProvider(ResourceProvider.getEntityProvider(Bid.class));
        container.addFilter(Filters.eq("auctionId", auction.getId()));
        container.applyFilters();

        final ArrayList<String> addrs = new ArrayList<String>();
        addrs.add(auction.getOwner().getEmail());

        for (final Object id : container.getItemIds()) {
            final Bid currentBid = container.getItem(id).getEntity();
            final String email = currentBid.getUser().getEmail();
            if (!addrs.contains(email)) {
                addrs.add(email);
            }
        }

        final String msg = "Auction Resolved: " + auction.getTitle();
        Email email;
        try {
            email = prepareMessage(msg, "Auction Resolved", addrs.toArray(new String[addrs.size()]));
            email.send();
        } catch (final Exception e) {
            e.printStackTrace();
        }
    }
}
